package com.atguigu.gulimall.order.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.exception.NoStockException;
import com.atguigu.common.to.SkuHasStockVo;
import com.atguigu.common.to.mq.OrderTo;
import com.atguigu.common.to.mq.SeckillOrdetInfoTo;
import com.atguigu.common.utils.R;
import com.atguigu.common.vo.MemberResponseVo;
import com.atguigu.gulimall.order.constant.OrderConstant;
import com.atguigu.gulimall.order.entity.OrderItemEntity;
import com.atguigu.gulimall.order.entity.PaymentInfoEntity;
import com.atguigu.gulimall.order.enume.OrderStatusEnum;
import com.atguigu.gulimall.order.feign.CartFeignService;
import com.atguigu.gulimall.order.feign.MemberFeignService;
import com.atguigu.gulimall.order.feign.ProductFeignService;
import com.atguigu.gulimall.order.feign.WmsFeignService;
import com.atguigu.gulimall.order.interceptor.LoginUserInterceptor;
import com.atguigu.gulimall.order.service.OrderItemService;
import com.atguigu.gulimall.order.service.PaymentInfoService;
import com.atguigu.gulimall.order.to.OrderCreateTo;
import com.atguigu.gulimall.order.vo.*;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.order.dao.OrderDao;
import com.atguigu.gulimall.order.entity.OrderEntity;
import com.atguigu.gulimall.order.service.OrderService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;


@Service("orderService")
public class OrderServiceImpl extends ServiceImpl<OrderDao, OrderEntity> implements OrderService {
    private ThreadLocal<OrderSubmitVo> submitVoThreadLocal = new ThreadLocal<>();

    @Autowired
    MemberFeignService memberFeignService;

    @Autowired
    CartFeignService cartFeignService;

    @Autowired
    ThreadPoolExecutor executor;

    @Autowired
    WmsFeignService wmsFeignService;

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    ProductFeignService productFeignService;

    @Autowired
    OrderService orderService;

    @Autowired
    OrderItemService orderItemService;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    PaymentInfoService paymentInfoService;



    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        OrderConfirmVo orderConfirmVo = new OrderConfirmVo();
        //获取之前线程的请求
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        //1、远程查询所有的会员地址
        CompletableFuture<Void> setMemberAddress = CompletableFuture.runAsync(() -> {
            //每一个线程都来共享之前的请求数据
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
            orderConfirmVo.setAddress(address);
        }, executor);


        //2.远程查询购物车所有的选中的购物项
        CompletableFuture<Void> setCartItems = CompletableFuture.runAsync(() -> {
            RequestContextHolder.setRequestAttributes(requestAttributes);
            List<OrderItemVo> cartItems = cartFeignService.getCurrentUserCartItems();
            orderConfirmVo.setItems(cartItems);
        }, executor).thenRunAsync(()->{
            List<OrderItemVo> confirmVoItems = orderConfirmVo.getItems();
            List<Long> skuIds = confirmVoItems.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
            List<SkuHasStockVo> skuHasStock = wmsFeignService.getSkuHasStock(skuIds);
            if(skuHasStock !=null){
                Map<Long, Boolean> stockMap = skuHasStock.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasHtock));
                orderConfirmVo.setStocks(stockMap);
            }
        },executor);


        CompletableFuture.allOf(setMemberAddress,setCartItems).get();
        //feign在远程调用之前要构造请求,调用很多的拦截器
        //RequestInterceptor interceptor : requestInterceptors

        //3.查询用户的积分
        Integer integration = memberResponseVo.getIntegration();
        orderConfirmVo.setIntegration(integration);

        //4.生成防重令牌
        String token = UUID.randomUUID().toString().replace("-", "");
        redisTemplate.opsForValue().set(OrderConstant.USER_ORDER_OKEN_PREFIX+memberResponseVo.getId(),token,30, TimeUnit.MINUTES);
        orderConfirmVo.setOrderToken(token);
        return orderConfirmVo;
    }

    /**
     * 1、远程服务假失败：
     *     远程服务其实成功了,由于网络故障等没有返回导致:订单回滚,库存却扣减了
     * 2、远程服务执行完成,下面的其他方法出现问题
     *     导致:以执行的远程请求,肯定不能回滚
     * 采用分布式事务,使用seata框架:
     *  1)、每一个微服务必须在数据库创建undo_log日志表
     *  2)、俺咋混个事务协调器:https://github.com/seata/seata
     *  3)、整合
     *      1、导入依赖 spring-cloud-starter-alibaba-seata seata-all:0.7.1
     *      2、解压并启动seata服务器
     *         regsitry.conf :注册中心配置: 修改registry type=nacos
     *         file.cof:用
     *     3、所有想要用到分布式事务的微服务都要使用seata DataSourceProxy代理自己的数据源
     *     4、每个微服务,都需要导入file.conf,regsitry.conf文件
     *     5、启动测试分布式事务
     *     6、给分布式大事务的入口处标注@GlobalTransactional
     *     7、每一个远程的小事务使用 @Transactional
     * @param orderSubmitVo
     * @return
     */
//    @GlobalTransactional //不适合高并发场景
    //使用可靠消息+最终一致性
    @Transactional
    @Override
    public SubmitOrderResponseVo submitOrder(OrderSubmitVo orderSubmitVo) {

        SubmitOrderResponseVo responseVo = new SubmitOrderResponseVo();
        responseVo.setCode(0);
        //通过threadlocal将页面传过来的数据进行共享
        submitVoThreadLocal.set(orderSubmitVo);
        //下单去创建订单,验令牌,锁库存。。。。
        //1.验证令牌【令牌的对比和删除必须保证原子性】
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        String orderToken = orderSubmitVo.getOrderToken();
        //0令牌失败 1令牌成功
        //原子验证令牌和删除令牌
        String script="if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Long result = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class),
                Arrays.asList(OrderConstant.USER_ORDER_OKEN_PREFIX + memberResponseVo.getId()),
                orderToken);
        if(result==0){
            //令牌验证失败
            responseVo.setCode(1);
            return responseVo;
        }else {
            //令牌验证成功
            //1、创建订单,订单项等信息
            OrderCreateTo orderCreateTo = createOrder();
            //2、验价
            BigDecimal payAmount = orderCreateTo.getOrder().getPayAmount();
            BigDecimal payPrice = orderSubmitVo.getPayPrice();
            if (Math.abs(payAmount.subtract(payPrice).doubleValue()) < 0.01) {
                //金额对比成功
                //3.保存订单到数据库
                saveOrder(orderCreateTo);
                //4.锁定库存,只要有异常回滚订单数据
                //订单号,所有订单项信息(skuId,skuName,num)
                WareSkuLockVo wareSkuLockVo = new WareSkuLockVo();
                wareSkuLockVo.setOrderSn(orderCreateTo.getOrder().getOrderSn());
                List<OrderItemVo> orderItemVos = orderCreateTo.getOrderItems().stream().map(item -> {
                    OrderItemVo orderItemVo = new OrderItemVo();
                    orderItemVo.setSkuId(item.getSkuId());
                    orderItemVo.setCount(item.getSkuQuantity());
                    orderItemVo.setTitle(item.getSpuName());
                    return orderItemVo;
                }).collect(Collectors.toList());
                wareSkuLockVo.setLocks(orderItemVos);
                //远程锁定库存,但是网络原因超时了,订单回滚,库存不滚
                //为了保证高并发,库存服务自己回滚。可以发消息给库存服务;
                //库存服务本身也可以使用自动解锁模式 使用消息队列
                R r = wmsFeignService.orderLockStock(wareSkuLockVo);
                if (r.getCode()==0) {
                    //调用成功,锁成功
                    responseVo.setOrderEntity(orderCreateTo.getOrder());
                    //5.远程扣减积分
                    //订单回滚,库存不滚
                    //订单创建成功,发送消息给MQ
                    rabbitTemplate.convertAndSend("order-event-exchange","order.create.order",orderCreateTo.getOrder());
                    return responseVo;
                }else {
                    //锁定失败
                    String msg = (String) r.get("msg");
                    throw new NoStockException(msg);
                }
            }else {
                responseVo.setCode(2);
                return responseVo;
            }
        }
    }

    /**
     * 保存订单的所有数据
     * @param orderCreateTo
     */
    private void saveOrder(OrderCreateTo orderCreateTo) {

        OrderEntity order = orderCreateTo.getOrder();
        order.setModifyTime(new Date());
        order.setCreateTime(new Date());
        orderService.save(order);
        List<OrderItemEntity> orderItems = orderCreateTo.getOrderItems();
        orderItemService.saveBatch(orderItems);

    }

    private OrderCreateTo createOrder(){
        OrderCreateTo orderCreateTo = new OrderCreateTo();
        //1.生成订单号
        String orderSn = IdWorker.getTimeId();
        //创建订单号
        OrderEntity orderEntity = buildOrder(orderSn);
        //2、获取所有的订单项
        List<OrderItemEntity> orderItemEntities = buildOrderItemList(orderSn);
        //3.验价，计算价格相关
        computerPrice(orderEntity,orderItemEntities);

        orderCreateTo.setOrder(orderEntity);
        orderCreateTo.setOrderItems(orderItemEntities);
        return orderCreateTo;
    }

    private void computerPrice(OrderEntity orderEntity, List<OrderItemEntity> orderItemEntities) {
        //1、订单价格相关
        BigDecimal total = new BigDecimal("0.0");
        BigDecimal totalCouponAmount = new BigDecimal("0.0");
        BigDecimal totalIntegrationAmount = new BigDecimal("0.0");
        BigDecimal totalPromotionAmount = new BigDecimal("0.0");
        BigDecimal totalGrowth= new BigDecimal("0.0");
        BigDecimal totalGiftIntegration= new BigDecimal("0.0");
        //遍历获取这个订单所有购物项累加起来的总额
        for (OrderItemEntity orderItemEntity : orderItemEntities) {
            //累加所有的购物项信息
            total = total.add(orderItemEntity.getRealAmount());
            //累加所有的优惠信息
            totalIntegrationAmount = totalPromotionAmount.add(orderItemEntity.getIntegrationAmount());
            totalCouponAmount = totalPromotionAmount.add(orderItemEntity.getCouponAmount());
            totalPromotionAmount = totalPromotionAmount.add( orderItemEntity.getPromotionAmount());
            //累加所有的积分
            totalGrowth = totalGrowth.add(new BigDecimal(orderItemEntity.getGiftGrowth().toString()));
            totalGiftIntegration = totalGiftIntegration.add(new BigDecimal(orderItemEntity.getGiftIntegration().toString()));
        }
        //设置订单的总额
        orderEntity.setTotalAmount(total);
        //设置应付金额,要加上运费
        orderEntity.setPayAmount(total.add(orderEntity.getFreightAmount()));
        //统计所有优惠的信息
        orderEntity.setPromotionAmount(totalPromotionAmount);
        orderEntity.setIntegrationAmount(totalIntegrationAmount);
        orderEntity.setCouponAmount(totalCouponAmount);
        //设置所有的积分信息
        orderEntity.setGrowth(totalGrowth.intValue());
        orderEntity.setIntegration(totalGiftIntegration.intValue());
        //设置订单删除状态 0未删除 1删除
        orderEntity.setDeleteStatus(0);
    }

    private OrderEntity buildOrder(String orderSn) {
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setOrderSn(orderSn);
        orderEntity.setMemberUsername(memberResponseVo.getNickname());
        //获取会员的id
        orderEntity.setMemberId(memberResponseVo.getId());
        //获取收货地址信息
        //获取邮费信息
        OrderSubmitVo orderSubmitVo = submitVoThreadLocal.get();
        R r = wmsFeignService.getFare(orderSubmitVo.getAddrId());
        FareVo fareResp = r.getData(new TypeReference<FareVo>() {
        });
        //设置收货运费信息
        orderEntity.setFreightAmount(fareResp.getFare());
        //设置收货人的信息
        orderEntity.setReceiverDetailAddress(fareResp.getMemberAddressVo().getDetailAddress());
        orderEntity.setReceiverName(fareResp.getMemberAddressVo().getName());
        orderEntity.setReceiverCity(fareResp.getMemberAddressVo().getCity());
        orderEntity.setReceiverPhone(fareResp.getMemberAddressVo().getPhone());
        orderEntity.setReceiverProvince(fareResp.getMemberAddressVo().getProvince());
        orderEntity.setReceiverPostCode(fareResp.getMemberAddressVo().getPostCode());
        orderEntity.setReceiverRegion(fareResp.getMemberAddressVo().getRegion());

        //设置订单的状态信息
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setAutoConfirmDay(7);
        return orderEntity;
    }

    /**
     * 构建所有订单项的数据
     * @return
     */
    private List<OrderItemEntity> buildOrderItemList(String orderSn) {
        //最后确定每一个购物项的价格
        List<OrderItemVo> currentUserCartItems = cartFeignService.getCurrentUserCartItems();
        if(currentUserCartItems!=null && currentUserCartItems.size()>0){
            List<OrderItemEntity> orderItemEntityList = currentUserCartItems.stream().map(cartItem -> {
                OrderItemEntity entity = bulidOrderItem(cartItem);
                entity.setOrderSn(orderSn);
                return entity;
            }).collect(Collectors.toList());
            return orderItemEntityList;
        }
        return null;
    }

    /**
     * 构建某一个的订单项
     * @param cartItem
     * @return
     */
    private OrderItemEntity bulidOrderItem(OrderItemVo cartItem) {
        OrderItemEntity itemEntity = new OrderItemEntity();
        //1.订单信息:订单号 v
        //2.商品的spu信息
        Long skuId = cartItem.getSkuId();
        R r = productFeignService.getSpuInfoBySkuId(skuId);
        SpuInfoVo spuInfoVo = r.getData(new TypeReference<SpuInfoVo>() {
        });
        itemEntity.setSpuId(spuInfoVo.getId());
        itemEntity.setSpuName(spuInfoVo.getSpuName());
        itemEntity.setSpuBrand(spuInfoVo.getBrandId().toString());
        itemEntity.setCategoryId(spuInfoVo.getCatalogId());
        //3.商品的sku信息 v
        itemEntity.setSkuId(cartItem.getSkuId());
        itemEntity.setSkuName(cartItem.getTitle());
        itemEntity.setSkuPic(cartItem.getImage());
        itemEntity.setSkuPrice(cartItem.getPrice());
        String skuAttr = StringUtils.collectionToDelimitedString(cartItem.getSkuAttr(), ";");
        itemEntity.setSkuAttrsVals(skuAttr);
        itemEntity.setSkuQuantity(cartItem.getCount());
        //4.优惠信息【不做】
        //5.积分信息
        itemEntity.setGiftGrowth(cartItem.getPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity())).intValue());
        itemEntity.setGiftIntegration(cartItem.getPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity())).intValue());
        //6.订单项的价格信息
        itemEntity.setPromotionAmount(new BigDecimal("0.0"));
        itemEntity.setCouponAmount(new BigDecimal("0.0"));
        itemEntity.setIntegrationAmount(new BigDecimal("0.0"));
        //当前订单项的实际金额,总额-各种优惠
        BigDecimal orign = itemEntity.getSkuPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity().toString()));
        BigDecimal realPrice = orign.subtract(itemEntity.getPromotionAmount())
                .subtract(itemEntity.getCouponAmount())
                .subtract(itemEntity.getIntegrationAmount());
        itemEntity.setRealAmount(realPrice);
        return itemEntity;
    }

    @Override
    public OrderEntity getOrderInfoByOrderSn(String orderSn) {
        OrderEntity order = this.baseMapper.selectOne(new QueryWrapper<OrderEntity>().eq("order_sn", orderSn));
        return order;
    }

    @Override
    public void closeOrder(OrderEntity entity) {
        OrderEntity order = this.getById(entity.getId());

        if(order.getStatus()==OrderStatusEnum.CREATE_NEW.getCode()){
            //关单
            OrderEntity updateOrder = new OrderEntity();
            updateOrder.setId(order.getId());
            updateOrder.setStatus(OrderStatusEnum.CANCLED.getCode());
            this.updateById(updateOrder);
            //给库存的MQ队列发一条信息
            OrderTo orderTo = new OrderTo();
            BeanUtils.copyProperties(order,orderTo);
            //TODO 保证消息一定会发出去，每一个消息都可以做好日志记录。(给数据库保存每一个消息的详细信息)
            //TODO 定期扫描数据库失败的消息在发送一遍

            try {
                rabbitTemplate.convertAndSend("order-event-exchange","order.release.other",orderTo);
            } catch (Exception e) {
                //将没发送成功额消息进行重试发送。
//                while
                e.printStackTrace();
            }
        }
    }

    @Override
    public PayVo getPayVoByOrderSn(String orderSn) {
        OrderEntity orderEntity = orderService.getOrderInfoByOrderSn(orderSn);
        PayVo payVo = new PayVo();
        payVo.setOut_trade_no(orderEntity.getOrderSn());
        payVo.setTotal_amount(orderEntity.getTotalAmount().setScale(2,BigDecimal.ROUND_UNNECESSARY).toString());
        List<OrderItemEntity> orderItemEntityList = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", orderSn));
        payVo.setSubject(orderItemEntityList.get(0).getSkuName());
        return payVo;
    }

    @Override
    public PageUtils queryPageWithItems(Map<String, Object> params) {
        IPage<OrderEntity> page = this.page(
                new Query<OrderEntity>().getPage(params),
                new QueryWrapper<OrderEntity>()
        );

        List<OrderEntity> entityList = page.getRecords().stream().map(order -> {
            List<OrderItemEntity> orderItemEntities = orderItemService.list(new QueryWrapper<OrderItemEntity>().eq("order_sn", order.getOrderSn()));
            order.setOrderItemEntities(orderItemEntities);
            return order;
        }).collect(Collectors.toList());

        page.setRecords(entityList);
        return new PageUtils(page);
    }

    @Override
    public String handlePayResult(PayAsyncVo payAsyncVo) {
        PaymentInfoEntity paymentInfoEntity = new PaymentInfoEntity();
        paymentInfoEntity.setCallbackTime(payAsyncVo.getNotify_time());
        paymentInfoEntity.setOrderSn(payAsyncVo.getOut_trade_no());
        paymentInfoEntity.setCreateTime(new Date());
        paymentInfoEntity.setSubject(payAsyncVo.getSubject());
        paymentInfoEntity.setTotalAmount(new BigDecimal(payAsyncVo.getBuyer_pay_amount()));
        paymentInfoEntity.setConfirmTime(new Date());
        paymentInfoEntity.setPaymentStatus(payAsyncVo.getTrade_status());
        paymentInfoEntity.setAlipayTradeNo(payAsyncVo.getTrade_no());

        paymentInfoService.save(paymentInfoEntity);

        if(payAsyncVo.getTrade_status().equals("TRADE_SUCCESS") || payAsyncVo.getTrade_status().equals("TRADE_FINISHED")){
            this.baseMapper.updatOrderPayStatus(payAsyncVo.getOut_trade_no(),OrderStatusEnum.PAYED.getCode());
        }
        System.out.println("签名验证成功。。。。。");
        return "success";
    }

    @Override
    @Transactional
    public void createSeckillOrder(SeckillOrdetInfoTo seckillEntity) throws ExecutionException, InterruptedException {
        //1.设置收货人信息,和邮费信息
        OrderEntity orderEntity = buildSeckillOrder(seckillEntity);
        BigDecimal skuPrice = seckillEntity.getSeckillPrice().multiply(new BigDecimal(seckillEntity.getNum()));
        //设置商品的总价
        orderEntity.setTotalAmount(skuPrice);
        //将邮费和秒杀商品总价相加
        orderEntity.setPayAmount(orderEntity.getFreightAmount().add(skuPrice));
        //存订单信息
        this.save(orderEntity);

        //构建订单项,并存订单项信息
        OrderItemEntity orderItemEntity = bulidSeckillSkuOrderItem(seckillEntity, orderEntity.getFreightAmount().add(skuPrice));
        orderItemService.save(orderItemEntity);
    }

    /**
     * 构建秒杀订单项
     * @param seckillEntity
     * @param realPayAmount
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    private OrderItemEntity bulidSeckillSkuOrderItem(SeckillOrdetInfoTo seckillEntity,BigDecimal realPayAmount) throws ExecutionException, InterruptedException {
        OrderItemEntity itemEntity = new OrderItemEntity();
        //1.订单信息:订单号
        itemEntity.setOrderSn(seckillEntity.getOrderSn());
        //2.商品的spu信息
//        Long skuId = cartItem.getSkuId();

        CompletableFuture<Void> getSpuInfoFuture = CompletableFuture.runAsync(() -> {
            R r = productFeignService.getSpuInfoBySkuId(seckillEntity.getSkuId());
            SpuInfoVo spuInfoVo = r.getData(new TypeReference<SpuInfoVo>() {
            });
            itemEntity.setSpuId(spuInfoVo.getId());
            itemEntity.setSpuName(spuInfoVo.getSpuName());
            itemEntity.setSpuBrand(spuInfoVo.getBrandId().toString());
            itemEntity.setCategoryId(spuInfoVo.getCatalogId());
        }, executor);

        //3.商品的sku信息
        itemEntity.setSkuId(seckillEntity.getSkuId());
        CompletableFuture<Void> getSkuInfoFuture = CompletableFuture.runAsync(() -> {
            R r = productFeignService.getSkuInfoBySkuId(seckillEntity.getSkuId());
            SkuInfoVo skuInfo = r.getData("skuInfo", new TypeReference<SkuInfoVo>() {
            });
            itemEntity.setSkuName(skuInfo.getSkuTitle());
            itemEntity.setSkuPic(skuInfo.getSkuDefaultImg());
            itemEntity.setSkuPrice(skuInfo.getPrice());
        }, executor);


        CompletableFuture<Void> skuAttrFuture = CompletableFuture.runAsync(() -> {
            String skuAttrString="";
            List<String> skuSaleAttrValues = productFeignService.getSkuSaleAttrValues(seckillEntity.getSkuId());
            for (int i=0;i<skuSaleAttrValues.size();i++){
                if(i==(skuSaleAttrValues.size()-1)){
                    skuAttrString = skuAttrString+skuSaleAttrValues.get(i);
                    break;
                }
                 skuAttrString = skuAttrString+skuSaleAttrValues.get(i)+";";
            }
            itemEntity.setSkuAttrsVals(skuAttrString);
        }, executor);

        //等异步方法全部执行完毕
        CompletableFuture.allOf(getSpuInfoFuture,getSkuInfoFuture,skuAttrFuture).get();

        itemEntity.setSkuQuantity(seckillEntity.getNum()); //秒杀抢购的数量
        //4.优惠信息【不做】
        //5.积分信息
//        itemEntity.setGiftGrowth(cartItem.getPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity())).intValue());
//        itemEntity.setGiftIntegration(cartItem.getPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity())).intValue());
        //6.订单项的价格信息
        itemEntity.setPromotionAmount(new BigDecimal("0.0"));
        itemEntity.setCouponAmount(new BigDecimal("0.0"));
        itemEntity.setIntegrationAmount(new BigDecimal("0.0"));
        //当前订单项的实际金额,总额-各种优惠，(秒杀没有优惠)
//        BigDecimal orign = itemEntity.getSkuPrice().multiply(new BigDecimal(itemEntity.getSkuQuantity().toString()));
//        BigDecimal realPrice = orign.subtract(itemEntity.getPromotionAmount())
//                .subtract(itemEntity.getCouponAmount())
//                .subtract(itemEntity.getIntegrationAmount());
        itemEntity.setRealAmount(realPayAmount);
        return itemEntity;
    }

    private OrderEntity buildSeckillOrder(SeckillOrdetInfoTo seckillOrdetInfoTo) throws ExecutionException, InterruptedException {
        OrderEntity orderEntity = new OrderEntity();


        CompletableFuture<MemberResponseVo> getMemberInfoFuture = CompletableFuture.supplyAsync(() -> {
            R r = memberFeignService.getMemberInfoByMemberId(seckillOrdetInfoTo.getMemberId());
            MemberResponseVo memberResponseVo = r.getData("member", new TypeReference<MemberResponseVo>() {
            });
            orderEntity.setOrderSn(seckillOrdetInfoTo.getOrderSn());
            orderEntity.setMemberUsername(memberResponseVo.getNickname());
            //获取会员的id
            orderEntity.setMemberId(memberResponseVo.getId());
            return memberResponseVo;
        }, executor);

        //获取收货地址信息
        //获取邮费信息
        CompletableFuture<Void> getFareInfoFuture = getMemberInfoFuture.thenAcceptAsync((res) -> {
            R r = wmsFeignService.getFare(res.getAddrId());
            FareVo fareResp = r.getData(new TypeReference<FareVo>() {
            });
            //设置收货运费信息
            orderEntity.setFreightAmount(fareResp.getFare());
            //设置收货人的信息
            orderEntity.setReceiverDetailAddress(fareResp.getMemberAddressVo().getDetailAddress());
            orderEntity.setReceiverName(fareResp.getMemberAddressVo().getName());
            orderEntity.setReceiverCity(fareResp.getMemberAddressVo().getCity());
            orderEntity.setReceiverPhone(fareResp.getMemberAddressVo().getPhone());
            orderEntity.setReceiverProvince(fareResp.getMemberAddressVo().getProvince());
            orderEntity.setReceiverPostCode(fareResp.getMemberAddressVo().getPostCode());
            orderEntity.setReceiverRegion(fareResp.getMemberAddressVo().getRegion());
        }, executor);

        //等待运费查询线程完毕
        getFareInfoFuture.get();

        //设置订单的状态信息
        orderEntity.setStatus(OrderStatusEnum.CREATE_NEW.getCode());
        orderEntity.setAutoConfirmDay(7);
        orderEntity.setCreateTime(new Date());
        orderEntity.setModifyTime(new Date());
        return orderEntity;
    }
}